package com.cory.admin.sys.service;

import java.util.List;
import java.util.stream.Collectors;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.beust.jcommander.internal.Lists;
import com.cory.admin.sys.domain.entity.SysDept;
import com.cory.admin.sys.mapper.SysDeptMapper;
import com.cory.boot.domain.chart.Tree;
import com.cory.boot.domain.enumdef.EOperateType;
import com.cory.boot.domain.enumdef.EState;
import com.cory.module.oplog.core.OpLogBaseService;
import com.cory.module.oplog.core.OpLogClient;
import com.cory.utils.lang.StringUtils;

/**
 *  服务实现类
 *
 * @author xc
 * @since 2022-01-14
 */
@Service
public class SysDeptService extends OpLogBaseService<SysDeptMapper, SysDept> {
    
    public SysDept getByCode(Integer tenantId, String code) {
        QueryWrapper<SysDept> query = new QueryWrapper<>();
        query.eq("tenant_id", tenantId).eq("code", code);
        return super.getOne(query);
    }
    
    public List<SysDept> getByCodes(Integer tenantId, List<String> codes) {
        if (codes == null || codes.size() == 0) {
            return Lists.newArrayList();
        }
        
        QueryWrapper<SysDept> query = new QueryWrapper<>();
        query.eq("tenant_id", tenantId).in("code", codes);
        return super.list(query);
    }

    public List<SysDept> sortList(SysDept param) {
        QueryWrapper<SysDept> query = new QueryWrapper<>();
        query.eq("tenant_id", param.getTenantId()).eq("user_type", param.getUserType()).ne("state", EState.DELETE.key);
        return sortList(super.list(query), "0");
    }
    
    private List<SysDept> sortList(List<SysDept> list, String rootId) {
        List<SysDept> sub = list.stream().filter(i -> rootId.equals(i.getParent())).collect(Collectors.toList());
        sub.sort((a, b) -> {
            return a.getSort() - b.getSort();
        });
        
        List<SysDept> ret = Lists.newArrayList();
        for (SysDept dept : sub) {
            ret.add(dept);
            ret.addAll(sortList(list, dept.getCode()));
        }
        
        return ret;
    }
    
    @Override
    public boolean save(SysDept entity) {
        Integer nowCode = baseMapper.maxCode(entity.getTenantId(), entity.getParent()) + 1;
        
        if ("0".equals(entity.getParent())) {
            entity.setCode(entity.getTenantId() + "B" + nowCode + "E");
        } else {
            entity.setCode(entity.getParent() + "B" + nowCode + "E");
        }
        
        boolean result = super.save2Log(entity);
        
        return result;
    }
    
    @Override
    @Transactional(rollbackFor=Exception.class)
    public boolean updateById(SysDept entity) {
        // 先不考虑修改上级部门，很麻烦
//        SysDept tmp = super.getById(entity.getId());
//        if (!tmp.getParent().equals(entity.getParent())) {
//            Integer maxCode = baseMapper.maxCode(tmp.getTenantId(), entity.getParent());
//            if ("0".equals(entity.getParent())) {
//                entity.setCode("#" + maxCode + "$");
//            } else {
//                entity.setCode(entity.getParent() + "#" + maxCode + "$");
//            }
//        }
        
        boolean result = super.updateById2Log(entity);
        return result;
    }
    
    @Override
    public boolean delete(Integer id) {
        SysDept tmp = super.getById(id);
        QueryWrapper<SysDept> query = new QueryWrapper<>();
        query.eq("tenant_id", tmp.getTenantId()).like("code", tmp.getCode() + "%");
        
        List<SysDept> list =super.list(query);
        List<Integer> idList = list.stream().map(i -> i.getId()).collect(Collectors.toList());
        boolean reslut = super.deleteByIds(idList);
        
        OpLogClient.addLog(SysDept.class, id, EOperateType.DELETE.key, EOperateType.DELETE.name);
        return reslut;
    }
    
    public List<Tree> selectTree(Integer tenantId, Integer userType) {
        QueryWrapper<SysDept> query = new QueryWrapper<>();
        query.eq("tenant_id", tenantId).eq("user_type", userType).ne("state", EState.DELETE.key);
        query.orderByAsc("parent").orderByAsc("sort");
        List<SysDept> depts = super.list(query);
        
        List<Tree> trees = Lists.newArrayList();
        for (SysDept dept : depts) {
            trees.add(new Tree(dept.getCode(), StringUtils.defaultIfBlank(dept.getParent(), "0"), dept.getName()));
        }
        
        trees.add(0, new Tree("0", "-1", "企业架构", true));
        return trees;
    }
}
